//
//  UIView+YJCornerAndShadow.m
//
//
//  Created by admin on 2020/10/16.
//

#import "UIView+YJCornerAndShadow.h"
#import <objc/runtime.h>


typedef struct {
     CGFloat topLeft;
     CGFloat topRight;
     CGFloat bottomLeft;
     CGFloat bottomRight;
} CornerRadii;

typedef CornerRadii(^ _Nonnull RadiiMaker)(void);

@interface UIView()

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, assign) BOOL isHaveShadow;

@end


@implementation UIView (YJCornerAndShadow)

#pragma mark - 切圆角
CornerRadii CornerRadiiMake(CGFloat topLeft,CGFloat topRight,CGFloat bottomLeft,CGFloat bottomRight) {
     return (CornerRadii){
          topLeft,
          topRight,
          bottomLeft,
          bottomRight,
     };
}

- (void)drawRectCornerRadiusMethod:(void(^)(void))complete {
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    CornerRadii radii = CornerRadiiMake(self.yj_cornerTopLeftRadius,
                                        self.yj_cornerTopRightRadius,
                                        self.yj_cornerBottomLeftRadius,
                                        self.yj_cornerBottomRightRadius);
    CGPathRef path = CYPathCreateWithRoundedRect(self.bounds,radii);
    shapeLayer.path = path;
//    shapeLayer.bounds = self.bounds;
    if (self.isHaveShadow) {
        [self addImageViewMethod];
        
        if ([self isKindOfClass:[UIImageView class]]) {
            [self imageViewCornerMethod:shapeLayer];
        }
        else {
            if (self.yj_image) {
                self.imageView.image = self.yj_image;
                self.imageView.layer.mask = shapeLayer;
            }
            else {
                [self cornerAndShadowMethod:shapeLayer];
                self.imageView.layer.mask = shapeLayer;
            }
        }
        
        self.layer.mask = nil;
    }else {
        if ([self isKindOfClass:[UIImageView class]]) {
            self.yj_image = self.yj_image;
        }
        if (self.yj_image) {
            [self addImageViewMethod];
            self.imageView.image = self.yj_image;
        }
        self.layer.mask = shapeLayer;
    }
    CGPathRelease(path);

    if (complete) {
        complete();
    }
}
/// UIImageView 处理   和   UIImageView 上面放其他类型 ，例如gif 片
- (void)imageViewCornerMethod:(CAShapeLayer *)shapeLayer {
    UIImageView *img = (UIImageView *)self;
    self.imageView.image = img.image;
    self.imageView.tag = 10211;
    if (self.subviews.count > 0) {
        for (UIView *view in self.subviews) {
            if (CGSizeEqualToSize(view.frame.size, self.frame.size)) {
                if (view.tag != 10211) {
                    view.layer.mask = shapeLayer;
                }
            }
        }
    }
    else {
        self.imageView.layer.mask = shapeLayer;
    }
}

/// 背景色 处理
- (void)cornerAndShadowMethod:(CAShapeLayer *)shapeLayer {
    self.imageView.backgroundColor = self.backgroundColor;
    self.backgroundColor = [UIColor clearColor];
}

- (void)addImageViewMethod {
    if (!self.imageView) {
         UIImageView *imageVieww = [[UIImageView alloc] init];
         imageVieww.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
         [self addSubview:imageVieww];
         [self sendSubviewToBack:imageVieww];
         self.imageView = imageVieww;
     }
}

//切圆角函数
CGPathRef CYPathCreateWithRoundedRect(CGRect bounds, CornerRadii cornerRadii) {
     const CGFloat minX = CGRectGetMinX(bounds);
     const CGFloat minY = CGRectGetMinY(bounds);
     const CGFloat maxX = CGRectGetMaxX(bounds);
     const CGFloat maxY = CGRectGetMaxY(bounds);
     
     const CGFloat topLeftCenterX = minX +  cornerRadii.topLeft;
     const CGFloat topLeftCenterY = minY + cornerRadii.topLeft;
     
     const CGFloat topRightCenterX = maxX - cornerRadii.topRight;
     const CGFloat topRightCenterY = minY + cornerRadii.topRight;
     
     const CGFloat bottomLeftCenterX = minX +  cornerRadii.bottomLeft;
     const CGFloat bottomLeftCenterY = maxY - cornerRadii.bottomLeft;
     
     const CGFloat bottomRightCenterX = maxX -  cornerRadii.bottomRight;
     const CGFloat bottomRightCenterY = maxY - cornerRadii.bottomRight;
     
     CGMutablePathRef path = CGPathCreateMutable();
     //顶 左
     CGPathAddArc(path, NULL, topLeftCenterX, topLeftCenterY,cornerRadii.topLeft, M_PI, 3 * M_PI_2, NO);
     //顶 右
     CGPathAddArc(path, NULL, topRightCenterX , topRightCenterY, cornerRadii.topRight, 3 * M_PI_2, 0, NO);
     //底 右
     CGPathAddArc(path, NULL, bottomRightCenterX, bottomRightCenterY, cornerRadii.bottomRight,0, M_PI_2, NO);
     //底 左
     CGPathAddArc(path, NULL, bottomLeftCenterX, bottomLeftCenterY, cornerRadii.bottomLeft, M_PI_2,M_PI, NO);
     CGPathCloseSubpath(path);
     return path;
}

- (void)setIsHaveShadow:(BOOL)isHaveShadow {
    objc_setAssociatedObject(self, @selector(isHaveShadow), @(isHaveShadow), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)isHaveShadow {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number boolValue];
}

- (void)setImageView:(UIImageView *)imageView {
    objc_setAssociatedObject(self, @selector(imageView), imageView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIImageView *)imageView {
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setYj_image:(UIImage *)yj_image {
    objc_setAssociatedObject(self, @selector(yj_image), yj_image, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIImage *)yj_image {
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setYj_cornerRadius:(CGFloat)cornerRadius {
    self.yj_cornerTopLeftRadius = cornerRadius;
    self.yj_cornerTopRightRadius = cornerRadius;
    self.yj_cornerBottomLeftRadius = cornerRadius;
    self.yj_cornerBottomRightRadius = cornerRadius;
    [self drawRectCornerRadiusMethod:nil];
    objc_setAssociatedObject(self, @selector(yj_cornerRadius), @(cornerRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)yj_cornerRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

- (void)setYj_cornerBottomRightRadius:(CGFloat)yj_cornerBottomRightRadius {
    objc_setAssociatedObject(self, @selector(yj_cornerBottomRightRadius), @(yj_cornerBottomRightRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.yj_cornerRadius <= 0 && yj_cornerBottomRightRadius > 0) {
        [self drawRectCornerRadiusMethod:nil];
    }
}
- (CGFloat)yj_cornerBottomRightRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

- (void)setYj_cornerTopLeftRadius:(CGFloat)yj_cornerTopLeftRadius {
    objc_setAssociatedObject(self, @selector(yj_cornerTopLeftRadius), @(yj_cornerTopLeftRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.yj_cornerRadius <= 0 && yj_cornerTopLeftRadius > 0) {
        [self drawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_cornerTopLeftRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

- (void)setYj_cornerTopRightRadius:(CGFloat)yj_cornerTopRightRadius {
    objc_setAssociatedObject(self, @selector(yj_cornerTopRightRadius), @(yj_cornerTopRightRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.yj_cornerRadius <= 0 && yj_cornerTopRightRadius > 0) {
        [self drawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_cornerTopRightRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

- (void)setYj_cornerBottomLeftRadius:(CGFloat)yj_cornerBottomLeftRadius {
    objc_setAssociatedObject(self, @selector(yj_cornerBottomLeftRadius), @(yj_cornerBottomLeftRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.yj_cornerRadius <= 0 && yj_cornerBottomLeftRadius > 0) {
        [self drawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_cornerBottomLeftRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

#pragma mark - 阴影

/// 设置默认阴影
- (void)yj_setShadowNormal{
    [self yj_setShadowByOpacity:0.5 shadowOffset:CGSizeMake(0,0) shadowRadius:3.0 shadowColor:[UIColor blackColor]];
}
/// 设置 阴影 透明度
- (void)yj_setShadowByOpacity:(CGFloat)shadowOpacity {
    [self yj_setShadowByOpacity:shadowOpacity shadowOffset:CGSizeMake(0,0) shadowRadius:3.0 shadowColor:[UIColor blackColor]];
}
/// 设置 阴影 偏移量
- (void)yj_setShadowByOffset:(CGSize)shadowOffset {
    [self yj_setShadowByOpacity:0.5 shadowOffset:shadowOffset shadowRadius:3.0 shadowColor:[UIColor blackColor]];
}
/// 设置 阴影 阴影半径
- (void)yj_setShadowByRadius:(CGFloat)shadowRadius {
    [self yj_setShadowByOpacity:0.5 shadowOffset:CGSizeMake(0,0) shadowRadius:shadowRadius shadowColor:[UIColor blackColor]];
}
/// 设置 阴影  阴影颜色
- (void)yj_setShadowByColor:(UIColor *)shadowColor {
    [self yj_setShadowByOpacity:0.5 shadowOffset:CGSizeMake(0,0) shadowRadius:3.0 shadowColor:shadowColor];
}

/// 设置 阴影 透明度 偏移量 阴影半径  阴影颜色
- (void)yj_setShadowByOpacity:(CGFloat)shadowOpacity
                    shadowOffset:(CGSize)shadowOffset
                  shadowRadius:(CGFloat)shadowRadius
                   shadowColor:(UIColor *)shadowColor {
    
    self.isHaveShadow = YES;
    [self drawRectCornerRadiusMethod:^{
        CornerRadii radii = CornerRadiiMake(self.yj_cornerTopLeftRadius,
                                            self.yj_cornerTopRightRadius,
                                            self.yj_cornerBottomLeftRadius,
                                            self.yj_cornerBottomRightRadius);
        CGPathRef path = CYPathCreateWithRoundedRect(self.bounds, radii);
        self.layer.shadowPath = path;
        // shadowColor阴影颜色
        self.layer.shadowColor = shadowColor.CGColor;
        // shadowOffset阴影偏移,x向右偏移3，y向下偏移2，默认(0, -3),这个跟shadowRadius配合使用
        self.layer.shadowOffset = shadowOffset;
        // 阴影透明度，默认0
        self.layer.shadowOpacity = shadowOpacity;
        // 阴影半径，默认3
        self.layer.shadowRadius = shadowRadius;
    }];

}


@end


@implementation CALayer (YJCornerAndShadow)

#pragma mark - 切圆角
CornerRadii YJLayerCornerRadiiMake(CGFloat topLeft,CGFloat topRight,CGFloat bottomLeft,CGFloat bottomRight) {
     return (CornerRadii){
          topLeft,
          topRight,
          bottomLeft,
          bottomRight,
     };
}

- (void)yjLayerDrawRectCornerRadiusMethod:(void(^)(void))complete {
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    CornerRadii radii = CornerRadiiMake(self.yj_layerCornerTopLeftRadius,
                                        self.yj_layerCornerTopRightRadius,
                                        self.yj_layerCornerBottomLeftRadius,
                                        self.yj_layerCornerBottomRightRadius);
    CGPathRef path = YJLayerPathCreateWithRoundedRect(self.bounds,radii);
    shapeLayer.path = path;
    self.mask = shapeLayer;
    CGPathRelease(path);

    if (complete) {
        complete();
    }
}

//切圆角函数
CGPathRef YJLayerPathCreateWithRoundedRect(CGRect bounds, CornerRadii cornerRadii) {
     const CGFloat minX = CGRectGetMinX(bounds);
     const CGFloat minY = CGRectGetMinY(bounds);
     const CGFloat maxX = CGRectGetMaxX(bounds);
     const CGFloat maxY = CGRectGetMaxY(bounds);
     
     const CGFloat topLeftCenterX = minX +  cornerRadii.topLeft;
     const CGFloat topLeftCenterY = minY + cornerRadii.topLeft;
     
     const CGFloat topRightCenterX = maxX - cornerRadii.topRight;
     const CGFloat topRightCenterY = minY + cornerRadii.topRight;
     
     const CGFloat bottomLeftCenterX = minX +  cornerRadii.bottomLeft;
     const CGFloat bottomLeftCenterY = maxY - cornerRadii.bottomLeft;
     
     const CGFloat bottomRightCenterX = maxX -  cornerRadii.bottomRight;
     const CGFloat bottomRightCenterY = maxY - cornerRadii.bottomRight;
     
     CGMutablePathRef path = CGPathCreateMutable();
     //顶 左
     CGPathAddArc(path, NULL, topLeftCenterX, topLeftCenterY,cornerRadii.topLeft, M_PI, 3 * M_PI_2, NO);
     //顶 右
     CGPathAddArc(path, NULL, topRightCenterX , topRightCenterY, cornerRadii.topRight, 3 * M_PI_2, 0, NO);
     //底 右
     CGPathAddArc(path, NULL, bottomRightCenterX, bottomRightCenterY, cornerRadii.bottomRight,0, M_PI_2, NO);
     //底 左
     CGPathAddArc(path, NULL, bottomLeftCenterX, bottomLeftCenterY, cornerRadii.bottomLeft, M_PI_2,M_PI, NO);
     CGPathCloseSubpath(path);
     return path;
}

- (void)setYj_layerCornerRadius:(CGFloat)layerCornerRadius {
    self.yj_layerCornerTopLeftRadius = layerCornerRadius;
    self.yj_layerCornerTopRightRadius = layerCornerRadius;
    self.yj_layerCornerBottomLeftRadius = layerCornerRadius;
    self.yj_layerCornerBottomRightRadius = layerCornerRadius;
    [self yjLayerDrawRectCornerRadiusMethod:nil];
    objc_setAssociatedObject(self, @selector(yj_layerCornerRadius), @(layerCornerRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)yj_layerCornerRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

- (void)setYj_layerCornerBottomRightRadius:(CGFloat)yj_layerCornerBottomRightRadius {
    objc_setAssociatedObject(self,
                             @selector(yj_layerCornerBottomRightRadius),
                             @(yj_layerCornerBottomRightRadius),
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.cornerRadius <= 0 && yj_layerCornerBottomRightRadius > 0) {
        [self yjLayerDrawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_layerCornerBottomRightRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

- (void)setYj_layerCornerTopLeftRadius:(CGFloat)yj_layerCornerTopLeftRadius {
    objc_setAssociatedObject(self, @selector(yj_layerCornerTopLeftRadius), @(yj_layerCornerTopLeftRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.cornerRadius <= 0 && yj_layerCornerTopLeftRadius > 0) {
        [self yjLayerDrawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_layerCornerTopLeftRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}


- (void)setYj_layerCornerTopRightRadius:(CGFloat)yj_layerCornerTopRightRadius {
    objc_setAssociatedObject(self, @selector(yj_layerCornerTopRightRadius), @(yj_layerCornerTopRightRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.cornerRadius <= 0 && yj_layerCornerTopRightRadius > 0) {
        [self yjLayerDrawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_layerCornerTopRightRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}


- (void)setYj_layerCornerBottomLeftRadius:(CGFloat)yj_layerCornerBottomLeftRadius {
    objc_setAssociatedObject(self,
                             @selector(yj_layerCornerBottomLeftRadius),
                             @(yj_layerCornerBottomLeftRadius),
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.cornerRadius <= 0 && yj_layerCornerBottomLeftRadius > 0) {
        [self yjLayerDrawRectCornerRadiusMethod:nil];
    }
}

- (CGFloat)yj_layerCornerBottomLeftRadius {
    NSNumber *number = objc_getAssociatedObject(self, _cmd);
    return [number floatValue] > 0 ? [number floatValue] : 0.0;
}

@end
